using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using MyPhotoIndex.Utilities.Types;
using System.Drawing.Design;
using MyPhotoIndex.Interfaces;
using MyPhotoIndex.Interfaces.Tagging;

namespace MyPhotoIndex.Controls
{
    public partial class TreeView : UserControl
    {
        public TreeView()
        {
            InitializeComponent();

            ((System.Windows.Forms.TreeView)this.tv1).AfterSelect += new TreeViewEventHandler(TreeView_AfterSelect);
            ((System.Windows.Forms.TreeView)this.tv1).NodeMouseClick += new TreeNodeMouseClickEventHandler(TreeView_NodeMouseClick);
            ((System.Windows.Forms.TreeView)this.tv1).NodeMouseDoubleClick += new TreeNodeMouseClickEventHandler(TreeView_NodeMouseDoubleClick);
            ((System.Windows.Forms.TreeView)this.tv1).MouseDown += new MouseEventHandler(TreeView_MouseDown);
            ((System.Windows.Forms.TreeView)this.tv1).MouseClick += new MouseEventHandler(TreeView_MouseClick);
            ((System.Windows.Forms.TreeView)this.tv1).AfterCheck += new TreeViewEventHandler(TreeView_AfterCheck);

            ((System.Windows.Forms.TreeView)this.tv1).DragEnter += new DragEventHandler(TreeView_DragEnter);
            ((System.Windows.Forms.TreeView)this.tv1).DragLeave += new EventHandler(TreeView_DragLeave);
            ((System.Windows.Forms.TreeView)this.tv1).DragOver += new DragEventHandler(TreeView_DragOver);
            ((System.Windows.Forms.TreeView)this.tv1).DragDrop += new DragEventHandler(TreeView_DragDrop);

            myPhotoIndexScrollBar1.ValueChanged += new EventHandler(myPhotoIndexScrollBar1_ValueChanged);
            tv1.ScrollUpdate += new EventHandler<ScrollValuesEventArgs>(tv1_ScrollUpdate);
            tv1.MouseWheel += new MouseEventHandler(tv1_MouseWheel);

            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);        
        }

        public override bool Focused
        {
            get
            {
                if (base.Focused ||
                    myPhotoIndexScrollBar1.Focused ||
                    tv1.Focused)
                {
                    return true;
                }

                return false;
            }
        }

        void tv1_ScrollUpdate(object sender, ScrollValuesEventArgs e)
        {
            try
            {
                myPhotoIndexScrollBar1.Maximum = e.Maximum;
                myPhotoIndexScrollBar1.Value = e.Value;

                myPhotoIndexScrollBar1.Enabled = (myPhotoIndexScrollBar1.Maximum == 0) ? false : true;
            }
            catch { }
        }

        void myPhotoIndexScrollBar1_ValueChanged(object sender, EventArgs e)
        {
            try
            {
                tv1.Scroll(myPhotoIndexScrollBar1.Value);
            }
            catch { }
        }

        void tv1_MouseWheel(object sender, MouseEventArgs e)
        {
            if (this.ClientRectangle.Contains(e.Location) == false)
            {
                base.OnMouseWheel(e);
                return;
            }

            if (e.Delta < 0)
            {
                if (myPhotoIndexScrollBar1.Value < myPhotoIndexScrollBar1.Maximum)
                {
                    myPhotoIndexScrollBar1.Value += myPhotoIndexScrollBar1.SmallChange;
                }
            }
            else
            {
                if (myPhotoIndexScrollBar1.Value > myPhotoIndexScrollBar1.Minimum)
                {
                    myPhotoIndexScrollBar1.Value -= myPhotoIndexScrollBar1.SmallChange;
                }
            }

            base.OnMouseWheel(e);
        }

        public bool ShowScrollBar
        {
            get { return myPhotoIndexScrollBar1.Visible; }
            set { myPhotoIndexScrollBar1.Visible = value; }
        }

        //
        // Summary:
        //     Occurs when a drag-and-drop operation is completed.
        new public event DragEventHandler DragDrop;

        void TreeView_DragDrop(object sender, DragEventArgs e)
        {
            if (DragDrop != null)
            {
                DragDrop.Invoke(this, e);
            }
        }
        //
        // Summary:
        //     Occurs when an object is dragged over the control's bounds.
        new public event DragEventHandler DragOver;

        void TreeView_DragOver(object sender, DragEventArgs e)
        {
            DragScroll(e);

            if (DragOver != null)
            {
                DragOver.Invoke(this, e);
            }
        }
        //
        // Summary:
        //     Occurs when an object is dragged out of the control's bounds.
        new public event EventHandler DragLeave;

        void TreeView_DragLeave(object sender, EventArgs e)
        {
            if (DragLeave != null)
            {
                DragLeave.Invoke(this, e);
            }
        }
        //
        // Summary:
        //     Occurs when an object is dragged into the control's bounds.
        new public event DragEventHandler DragEnter;

        void TreeView_DragEnter(object sender, DragEventArgs e)
        {
            if (DragEnter != null)
            {
                DragEnter.Invoke(this, e);
            }
        }

        //
        // Summary:
        //     Occurs when the control is clicked by the mouse.
        public new event MouseEventHandler MouseClick;

        void TreeView_MouseClick(object sender, MouseEventArgs e)
        {
            if (MouseClick != null)
            {
                MouseClick.Invoke(this, e);
            }
        }

        //
        // Summary:
        //     Occurs when the mouse pointer is over the control and a mouse button is pressed.
        public new event MouseEventHandler MouseDown;
        void TreeView_MouseDown(object sender, MouseEventArgs e)
        {
            if (MouseDown != null)
            {
                MouseDown.Invoke(this, e);
            }
        }

        // Summary:
        //     Occurs after the tree node check box is checked.
        public event TreeViewEventHandler AfterCheck;
        void TreeView_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (AfterCheck != null)
            {
                AfterCheck.Invoke(this, e);
            }
        }

        public event TreeNodeMouseClickEventHandler NodeMouseClick;

        void TreeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (NodeMouseClick != null)
            {
                NodeMouseClick.Invoke(this, e);
            }
        }

        //
        // Summary:
        //     Occurs when the user double-clicks a System.Windows.Forms.TreeNode with the
        //     mouse.
        public event TreeNodeMouseClickEventHandler NodeMouseDoubleClick;

        void TreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (NodeMouseDoubleClick != null)
            {
                NodeMouseDoubleClick.Invoke(this, e);
            }
        }

        public event TreeViewEventHandler AfterSelect;

        void TreeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (AfterSelect != null)
            {
                AfterSelect.Invoke(this, e);
            }
        }

        private void DragScroll(DragEventArgs e)
        {
            // Set a constant to define the autoscroll region
            const Single scrollRegion = 20;

            // See where the cursor is
            Point pt = this.PointToClient(Cursor.Position);

            int value = this.myPhotoIndexScrollBar1.Value;

            // See if we need to scroll up or down
            if ((pt.Y + scrollRegion) > this.Height)
            {
                if (value + 1 < this.myPhotoIndexScrollBar1.Maximum)
                {
                    this.myPhotoIndexScrollBar1.Value++;
                }
            }
            else if (pt.Y < (this.Top + scrollRegion))
            {
                if (value - 1 >= this.myPhotoIndexScrollBar1.Minimum)
                {
                    this.myPhotoIndexScrollBar1.Value--;
                }
            }
        }

        public enum DisplayTypeEnum { Classic = 0, Outlook = 1 }
        public DisplayTypeEnum DisplayType
        {
            get { return this.tv1.DisplayType; }
            set { this.tv1.DisplayType = value; }
        }

        public bool CheckBoxes
        {
            get { return this.tv1.CheckBoxes; }
            set { this.tv1.CheckBoxes = value; }
        }

        public bool Icons
        {
            get { return this.tv1.Icons; }
            set { this.tv1.Icons = value; }
        }

        public IImageTag GetTag(int id)
        {
            return this.tv1.GetTag(id);
        }

        public TreeNode[] GetCheckedNodes()
        {
            return this.tv1.GetCheckedNodes();
        }

        public IEnumerable<TreeNode> FilteredNodes
        {
            get
            {
                return this.tv1.FilteredNodes;
            }
        }

        public void UncheckAll()
        {
            this.tv1.UncheckAll();
        }

        public new void Load(IImageTagCollection tagFactory)
        {
            this.tv1.Load(tagFactory);
        }

        public bool Sorted
        {
            get { return ((System.Windows.Forms.TreeView)this.tv1).Sorted; }
            set { ((System.Windows.Forms.TreeView)this.tv1).Sorted = value; }
        }

        public bool HotTracking
        {
            get { return ((System.Windows.Forms.TreeView)this.tv1).HotTracking; }
            set { ((System.Windows.Forms.TreeView)this.tv1).HotTracking = value; }
        }

        public bool ShowLines
        {
            get { return ((System.Windows.Forms.TreeView)this.tv1).ShowLines; }
            set { ((System.Windows.Forms.TreeView)this.tv1).ShowLines = value; }
        }

        public bool ShowPlusMinus
        {
            get { return ((System.Windows.Forms.TreeView)this.tv1).ShowPlusMinus; }
            set { ((System.Windows.Forms.TreeView)this.tv1).ShowPlusMinus = value; }
        }

        public bool ShowRootLines
        {
            get { return ((System.Windows.Forms.TreeView)this.tv1).ShowRootLines; }
            set { ((System.Windows.Forms.TreeView)this.tv1).ShowRootLines = value; }
        }

        //
        // Summary:
        //     Gets or sets the image list index value of the image that is displayed when
        //     a tree node is selected.
        //
        // Returns:
        //     A zero-based index value that represents the position of an System.Drawing.Image
        //     in an System.Windows.Forms.ImageList.
        //
        // Exceptions:
        //   System.ArgumentException:
        //     The index assigned value is less than zero.
        [Localizable(true)]
        [DefaultValue(-1)]
        [Editor("System.Windows.Forms.Design.ImageIndexEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
        [RelatedImageList("ImageList")]
        public int SelectedImageIndex 
        {
            get { return tv1.SelectedImageIndex; }
            set { tv1.SelectedImageIndex = value; } 
        }

        [Editor("System.Windows.Forms.Design.ImageIndexEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
        [RefreshProperties(RefreshProperties.Repaint)]
        [DefaultValue(-1)]
        [RelatedImageList("ImageList")]
        [Localizable(true)]
        public int ImageIndex
        {
            get { return ((System.Windows.Forms.TreeView)this.tv1).ImageIndex; }
            set { ((System.Windows.Forms.TreeView)this.tv1).ImageIndex = value; }
        }

        [Localizable(true)]
        [TypeConverter(typeof(ImageKeyConverter))]
        [Editor("System.Windows.Forms.Design.ImageIndexEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
        [DefaultValue("")]
        [RefreshProperties(RefreshProperties.Repaint)]
        [RelatedImageList("ImageList")]
        public string ImageKey
        {
            get { return ((System.Windows.Forms.TreeView)this.tv1).ImageKey; }
            set { ((System.Windows.Forms.TreeView)this.tv1).ImageKey = value; }
        }

        [RefreshProperties(RefreshProperties.Repaint)]
        [DefaultValue("")]
        public ImageList ImageList
        {
            get { return ((System.Windows.Forms.TreeView)this.tv1).ImageList; }
            set { ((System.Windows.Forms.TreeView)this.tv1).ImageList = value; }
        }

        public int ItemHeight
        {
            get { return ((System.Windows.Forms.TreeView)this.tv1).ItemHeight; }
            set { ((System.Windows.Forms.TreeView)this.tv1).ItemHeight = value; }
        }

        public bool ShowNodeToolTips
        {
            get { return ((System.Windows.Forms.TreeView)this.tv1).ShowNodeToolTips; }
            set { ((System.Windows.Forms.TreeView)this.tv1).ShowNodeToolTips = value; }
        }

        //
        // Summary:
        //     Gets or sets the tree node that is currently selected in the tree view control.
        //
        // Returns:
        //     The System.Windows.Forms.TreeNode that is currently selected in the tree
        //     view control.
        [Browsable(false)]
        [DesignerSerializationVisibility(0)]
        public TreeNode SelectedNode 
        {
            get { return ((System.Windows.Forms.TreeView)this.tv1).SelectedNode; }
            set { ((System.Windows.Forms.TreeView)this.tv1).SelectedNode = value; }
        }

        //
        // Summary:
        //     Gets the collection of tree nodes that are assigned to the tree view control.
        //
        // Returns:
        //     A System.Windows.Forms.TreeNodeCollection that represents the tree nodes
        //     assigned to the tree view control.
        [Localizable(true)]
        [MergableProperty(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public TreeNodeCollection Nodes 
        {
            get { return ((System.Windows.Forms.TreeView)this.tv1).Nodes; }
        }

        public TreeNode GetNodeAt(Point point)
        {
            return ((System.Windows.Forms.TreeView)this.tv1).GetNodeAt(point);
        }

        public void UpdateTreeNodesHeight()
        {
            this.tv1.UpdateTreeNodesHeight();
        }

        public void Sort()
        {
            this.tv1.Sort();
        }

        public int ScrollOffset
        {
            get
            {
                return this.myPhotoIndexScrollBar1.Value;
            }
            set
            {
                this.myPhotoIndexScrollBar1.Value = value;
            }
        }

        public List<TreeNode> SelectedNodes
        {
            get
            {
                return this.tv1.SelectedNodes;
            }
        }
    }
}
